package util;

import com.maxmind.geoip2.DatabaseReader;
import com.maxmind.geoip2.model.CityResponse;
import com.maxmind.geoip2.record.*;
import org.apache.commons.lang3.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.net.InetAddress;

/**
 * IP工具类，
 * 需要去http://dev.maxmind.com/geoip/geoip2/geolite2/下载数据库
 * 下载位置： 列名：“MaxMind DB binary, gzipped”， 行名：“GeoLite2 City”的链接
 * 数据库文件名：GeoLite2-City_20191119.tar.gz
 * @author wevil
 * @date 2019/11/23
 * */
public class IpAddressUtil {

    /** 本机IP */
    private static String HOST_IP = "127.0.0.1";

    /**
     * 获取Ip地址
     * @param request http请求
     */
    public static String getIpAddress(HttpServletRequest request) {
        String Xip = request.getHeader("X-Real-IP");
        String XFor = request.getHeader("X-Forwarded-For");
        if(StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)){
            //多次反向代理后会有多个ip值，第一个ip才是真实ip
            int index = XFor.indexOf(",");
            if(index != -1){
                return XFor.substring(0,index);
            }else{
                return XFor;
            }
        }
        XFor = Xip;
        if(StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)){
            return XFor;
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("Proxy-Client-IP");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("WL-Proxy-Client-IP");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("HTTP_CLIENT_IP");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
        }
        if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
            XFor = request.getRemoteAddr();
        }
        return XFor;
    }

    /**
     * 通过IP获取城市
     * @param ip ip地址
     * */
    public static String getCityByIP(String ip)  {
        try{
            // 创建 GeoLite2 数据库
            String rootPath = IpAddressUtil.class.getProtectionDomain().getCodeSource().getLocation().getPath();
            File database = new File(rootPath + "db/GeoLite2-City.mmdb");
            // 读取数据库内容
            DatabaseReader reader = new DatabaseReader.Builder(database).build();
            InetAddress ipAddress = InetAddress.getByName(ip);

            // 获取查询结果
            CityResponse response = reader.city(ipAddress);

            // 获取国家信息
            Country country = response.getCountry();
            //System.out.println(country.getIsoCode());               // 'CN'
            //System.out.println(country.getName());                  // 'China'
            //System.out.println(country.getNames().get("zh-CN"));    // '中国'

            // 获取省份
            Subdivision subdivision = response.getMostSpecificSubdivision();
            //System.out.println(subdivision.getName());   // 'Guangxi Zhuangzu Zizhiqu'
            //System.out.println(subdivision.getIsoCode()); // '45'
            //System.out.println(subdivision.getNames().get("zh-CN")); // '广西壮族自治区'

            // 获取城市
            City city = response.getCity();
            //System.out.println(city.getName()); // 'Nanning'
            Postal postal = response.getPostal();
            //System.out.println(postal.getCode()); // 'null'
            //System.out.println(city.getNames().get("zh-CN")); // '南宁'
            Location location = response.getLocation();
            //System.out.println(location.getLatitude());  // 22.8167
            //System.out.println(location.getLongitude()); // 108.3167
            return city.getNames().get("zh-CN");
        }catch(Exception e){
            if(HOST_IP.equals(ip)){
                return "本机";
            }
            return "未知IP地址：" + ip;
        }
    }
}
